// File: jmcomic-core/src/main/java/dev/jukomu/jmcomic/plugin/AbstractJmOptionPlugin.java
package dev.jukomu.jmcomic.plugin;

import dev.jukomu.common.util.file.FileUtils;
import dev.jukomu.jmcomic.config.JmModuleConfig;
import dev.jukomu.jmcomic.entity.JmAlbumDetail;
import dev.jukomu.jmcomic.entity.JmPhotoDetail;
import dev.jukomu.jmcomic.option.DirRule;
import dev.jukomu.jmcomic.option.JmOption;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * JmOptionPlugin接口的抽象实现，提供通用方法的默认实现。
 */
public abstract class AbstractJmOptionPlugin implements JmOptionPlugin {

    protected final JmOption option; // 关联的JmOption实例
    protected boolean logEnable = true; // 日志开关
    protected boolean deleteOriginalFile = false; // 是否删除原文件

    public AbstractJmOptionPlugin(JmOption option) {
        this.option = Objects.requireNonNull(option, "JmOption cannot be null.");
    }

    @Override
    public void setLogEnable(boolean logEnable) {
        this.logEnable = logEnable;
    }

    @Override
    public void log(String msg, String topic) {
        if (logEnable) {
            String fullTopic = "plugin." + getPluginKey() + (topic != null ? "." + topic : "");
            JmModuleConfig.jmLog(fullTopic, msg);
        }
    }

    @Override
    public void requireParam(boolean condition, String message) throws PluginValidationException {
        if (!condition) {
            throw new PluginValidationException(this, message);
        }
    }

    @Override
    public void warningLibNotInstall(String lib, boolean doThrow) throws PluginValidationException {
        String msg = String.format("插件`%s`依赖库: %s，请先安装%s再使用。安装命令: [pip install %s]", getPluginKey(), lib, lib, lib);
        log(msg, "warning.lib_not_install");
        if (doThrow) {
            requireParam(false, msg);
        }
    }

    @Override
    public void executeDeletion(List<String> paths) {
        if (!deleteOriginalFile) {
            return;
        }

        for (String p : paths) {
            try {
                if (Files.isDirectory(Paths.get(p))) {
                    if (FileUtils.filesOfDir(p).isEmpty()) {
                        Files.delete(Paths.get(p));
                        log("删除文件夹: " + p, "remove");
                    } else {
                        log("文件夹中存在非本次下载的文件，请手动删除文件夹内的文件: " + p, "remove.ignore");
                    }
                } else if (Files.exists(Paths.get(p))) {
                    Files.delete(Paths.get(p));
                    log("删除原文件: " + p, "remove");
                }
            } catch (IOException e) {
                log("删除文件/目录失败: " + p + "，原因: " + e.getMessage(), "remove.error");
            }
        }
    }

    @Override
    public int executeCmd(String cmd) {
        log("在Java核心库中不支持执行shell命令。", "unsupported.exec");
        throw new UnsupportedOperationException("Executing shell commands is not supported in jmcomic-core.");
    }

    @Override
    public void executeMultiLineCmd(String cmd) {
        log("在Java核心库中不支持执行多行shell命令。", "unsupported.exec");
        throw new UnsupportedOperationException("Executing multi-line shell commands is not supported in jmcomic-core.");
    }

    @Override
    public void enterWaitList() {
        option.getNeedWaitPlugins().add(this);
    }

    @Override
    public void leaveWaitList() {
        option.getNeedWaitPlugins().remove(this);
    }

    @Override
    public void waitUntilFinish() {
        // 默认空实现，需要后台任务的插件应覆盖此方法
    }

    @Override
    public String decideFilepath(JmAlbumDetail album, JmPhotoDetail photo, String filenameRule, String suffix, String baseDir, Map<String, Object> dirRuleDict) {
        String finalBaseDir = (baseDir != null) ? baseDir : System.getProperty("user.dir");
        DirRule dirRule;
        String filepath;

        if (dirRuleDict != null && !dirRuleDict.isEmpty()) {
            dirRule = new DirRule((String) dirRuleDict.get("rule"), (String) dirRuleDict.getOrDefault("base_dir", finalBaseDir));
            filepath = dirRule.applyRuleToPath(album, photo, false);
        } else {
            filepath = finalBaseDir + java.io.File.separator + DirRule.applyRuleToFilename(album, photo, filenameRule) + FileUtils.fixSuffix(suffix);
        }

        try {
            FileUtils.mkdirIfNotExists(FileUtils.getDirPath(filepath, false));
        } catch (IOException e) {
            throw new RuntimeException("Failed to create directory for filepath: " + filepath, e);
        }

        return filepath;
    }
}